﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

using VDataAdapter.Communication;
using VDataAdapter.QueueManagement;
using VDataAdapter.EventManagement;
using PriceLibrary.ChartService;

namespace VDataAdapter.WorkerManagement
{
    class TransactionWorkerException : Exception
    {
        public TransactionWorkerException() : base() { }

        public TransactionWorkerException(string message) : base(message) { }

        public TransactionWorkerException(string message, Exception innerException) : base(message, innerException) { }
    }

    class TransactionWorker : Worker
    {
        private VDataCommunicator _sender;

        private IEventProviderQueue _queue;

        private TransactionBuffer _buffer;

        private EventQueueChecker _queueChecker;

        /// <summary>
        /// This worker is hardworking by default
        /// </summary>
        /// <param name="waitFirstTime"></param>
        /// <param name="endRecovery"></param>
        /// <param name="sender"></param>
        /// <param name="queue"></param>
        public TransactionWorker(string parentName,ManualResetEvent waitFirstTime, ManualResetEvent endRecovery, VDataCommunicator sender, IEventProviderQueue queue)
            : base(waitFirstTime, endRecovery, true)
        {
            _sender = sender;
            _queue = queue;
            _buffer = new TransactionBuffer();
            _queueChecker = new TimeOutQueueChecker(queue, 20);
            _name = parentName+"-TransactionWorker";

        }
      

        public bool StopCheckQueue
        {
            get { return _queueChecker.StopCheckingQueue; }
            set { _queueChecker.StopCheckingQueue = value; }
        }

        override
        public void StopWork()
        {
            StopCheckQueue = true;
        }


        /// <summary>
        /// Send data to queue
        /// </summary>
        /// <param name="data"></param>
        protected override void DoWork(object data)
        {
            try
            {   
                var e = (TransactionsEvent)_queueChecker.CheckingQueue(EventType.Transaction);

                if (e == null)
                { 
                    // stop checking there is none, exist now
                    IsHardWorking = false;
                    _sender.SendFlag(MessageFlagSequeue.END_RECOVERY);
                    return;
                }

                // if I haven't receive all event yet, I'll wait for more
                if (!_buffer.ReceivedTransaction(e.TransactionsList, e.CountNumber, e.TotalCountNumber))
                    return;

                List<Transaction> dataToSend = _buffer.Transactions;

                foreach (Transaction transaction in dataToSend)
                    _sender.SendTransaction(transaction);

                _sender.SendFlag(MessageFlagSequeue.END_RECOVERY);


                // now I can rest
                IsHardWorking = false;
            }
            catch(Exception ex)
            {
                throw new TransactionWorkerException("Unknown error occurred: ", ex);
            }

        }
    
    }
}
